//
//  HBarChart.swift
//  Time
//
//  Created by hushaohua on 2017/3/24.
//  Copyright © 2017年 init. All rights reserved.
//

import UIKit

class HBarChartConfigruation : HLinearChartConfiguration{
    enum KeyStyle{
        case horizontal
        case vertical
    }
    var keyStyle:KeyStyle = .horizontal;
    
    override func xAxisEdge() -> CGFloat{
        switch self.keyStyle {
        case .horizontal:
            return self.valueAxisHeight();
        case .vertical:
            return 0;
        }
    }
    override func yAxisEdge() -> CGFloat{
        switch self.keyStyle {
        case .horizontal:
            return self.keyAxisHeight();
        case .vertical:
            return 0;
        }
    }
    
    var barSpace:CGFloat = 20;
    var barWidth:CGFloat?;
    var barColor:UIColor = UIColor.black;
}

class HBarChartView: HLinearChartView {

    override func linearConfiguration() -> HLinearChartConfiguration{
        let config = HBarChartConfigruation();
        config.keyAxisPref = HChartAxisPreference();
        config.valueAxisPref = HChartAxisPreference();
        return config;
    }

    func barConfig() -> HBarChartConfigruation{
        return self.configuration as! HBarChartConfigruation;
    }
    override func draw(_ rect: CGRect) {
        switch self.barConfig().keyStyle {
        case .horizontal:
            self.drawHorizontally();
        default:
            break
        }
    }
    
    override func prepareChartItemsData() {
        super.prepareChartItemsData();
        self.getChartBarRects();
    }
    
    func keysWidth() -> CGFloat {
        let config = self.barConfig();
        switch self.barConfig().keyStyle {
        case .horizontal:
            return self.bounds.size.width - config.valueAxisHeight();
        case .vertical:
            return self.bounds.size.height - config.valueAxisHeight();
        }
    }
    func valuesWidth() -> CGFloat {
        let config = self.barConfig();
        switch self.barConfig().keyStyle {
        case .horizontal:
            return self.bounds.size.height - config.keyAxisHeight() - config.valueHeight();
        case .vertical:
            return self.bounds.size.width - config.keyAxisHeight();
        }
    }
    
    func getChartBarRects() {
        var barWidth:CGFloat = 0;
        if (self.barConfig().barWidth == nil){
            barWidth = (self.keysWidth() - CGFloat(self.chartItems!.count + 1) * self.barConfig().barSpace) / CGFloat(self.chartItems!.count);
        }else{
            barWidth = self.barConfig().barWidth!;
        }
        switch self.barConfig().keyStyle {
        case .horizontal:
            self.getHorizontalChartRects(barWidth);
        default:
            break;
        }
    }
    
    var horizontalWidth:CGFloat = 0;
    
    func getHorizontalChartRects(_ barWidth:CGFloat) {
        let config = self.barConfig();
        var xOffset:CGFloat = config.valueAxisHeight();
        let keyTextAttributes:[NSAttributedStringKey:Any]? = config.keyAxisPref?.textAttributes;
        let valueTextAttributes:[NSAttributedStringKey:Any]? = config.valuePref?.textAttributes;
        for aChart in self.chartItems! {
            let chart:HBarChartItem = aChart as! HBarChartItem;
            let barSpace = self.barConfig().barSpace;
            chart.barRect.origin.x = xOffset + barSpace;
            chart.barRect.size.width = barWidth;
            chart.barRect.size.height = self.valuesWidth() * CGFloat(chart.value) / CGFloat(self.maxValue);
            chart.barRect.origin.y = config.valueHeight() + self.valuesWidth() - chart.barRect.size.height;
            
            if (keyTextAttributes != nil){
                let string:NSString = NSString(string: chart.key);
                let size = string.boundingRect(with: CGSize(width:barWidth + config.barSpace, height:config.keyAxisHeight()), options: .usesLineFragmentOrigin, attributes: keyTextAttributes, context: nil);
                chart.keyRect.size.width = size.width;
                chart.keyRect.size.height = size.height;
                chart.keyRect.origin.x = xOffset + self.barConfig().barSpace / 2 + (self.barConfig().barSpace + barWidth - size.width) / 2;
                chart.keyRect.origin.y = config.valueHeight() + self.valuesWidth() + (config.keyAxisHeight() - size.height) / 2;
            }
            if (valueTextAttributes != nil){
                let string:NSString = NSString(string: chart.valueString);
                let size = string.boundingRect(with: CGSize(width:barWidth + config.barSpace, height:config.valueHeight()), options: .usesLineFragmentOrigin, attributes: valueTextAttributes, context: nil);
                chart.valueRect.size.width = size.width;
                chart.valueRect.size.height = size.height;
                chart.valueRect.origin.x = xOffset + self.barConfig().barSpace / 2 + (self.barConfig().barSpace + barWidth - size.width) / 2;
                chart.valueRect.origin.y = chart.barRect.origin.y - config.valueHeight();
            }
            
            xOffset = chart.barRect.maxX;
        }
        self.horizontalWidth = xOffset;
    }
    
//    var disableValue:Bool = false;
    func drawHorizontally(){
        self.drawHorizontalKeyAxis();
        self.drawKeyTexts();
        self.drawHorizontalValueAxis();
        self.drawValues();
//        if (!self.disableValue){
//            self.drawValueTexts();
//            self.drawXBaselines();
//        }
        self.drawBars();
    }
    
    func drawHorizontalKeyAxis(){
        if (self.barConfig().keyAxisPref != nil){
            self.drawKeyAxis();
        }
    }
    
    func drawHorizontalValueAxis(){
        if (self.barConfig().valueAxisPref != nil){
            self.drawValueAxis();
        }
    }
    func drawBars(){
        let context:CGContext = UIGraphicsGetCurrentContext()!;
        context.beginPath();
        var rects:[CGRect] = [CGRect]();
        for aChart in self.chartItems! {
            let chart:HBarChartItem = aChart as! HBarChartItem;
            rects.append(chart.barRect);
        }
        context.addRects(rects);
        context.closePath();
        self.barConfig().barColor.setFill();
        context.drawPath(using: .fill);
    }
}
